import moment from 'moment';
import _ from 'lodash';
import HttpClient from '../commons/http-client';
import {FormStatus, LoadingStatus, updateAppState} from '../reducers/app-state';
import {
  appendOrderList,
  refreshOrderList,
  updateOrderList,
} from '../reducers/order-list';
import {
  createOrder,
  createOrderProductAdd,
  createOrderProductUpdate,
} from '../reducers/create-order';
import {updateOrder, resetOrder} from '../reducers/order';
import {UserType} from '../reducers/user';
import Toast from '../components/toast';
import {I18n} from '../reducers/intl';

export function loadOrders(form, page) {
  return async (dispatch, getState) => {
    const {user} = getState();
    const params = {
      clinic: form.clinic || '',
      dentist: form.dentist || '',
      technician: form.technician || '',
      vendor: form.provider || '',
      state: form.status || '',
      product_type: form.type || '',
      search: form.keyword || '',
      page: page,
    };
    try {
      dispatch(updateAppState({loading: LoadingStatus.PENDING}));
      const url = `/web/${
        [UserType.dentist, UserType.clinic].includes(user.type)
          ? 'dent'
          : 'vend'
      }/order?expand=buyer%2Citems%2Cmessages%2Cseller.busy_dates%2Cpraise&${HttpClient.encodeParams(
        params,
      )}`;
      // console.log(url, params);
      const ordersRep = await HttpClient.get(url);

      // console.log('page', page);
      // console.log('ordersRep', ordersRep);
      if (page > 1) {
        dispatch(
          appendOrderList({
            total: _.get(ordersRep, 'data.data.count', 0),
            current: _.get(ordersRep, 'data.data.current', 0),
            items: _.get(ordersRep, 'data.data.results', []),
          }),
        );
      } else {
        dispatch(
          refreshOrderList({
            total: _.get(ordersRep, 'data.data.count', 0),
            current: _.get(ordersRep, 'data.data.current', 0),
            items: _.get(ordersRep, 'data.data.results', []),
          }),
        );
      }
      dispatch(loadChoices(user));
      dispatch(updateAppState({loading: LoadingStatus.DONE}));
    } catch (e) {
      dispatch(updateAppState({loading: LoadingStatus.ERROR}));
      if (e.message === 'Request failed with status code 404') {
        return Toast.show(I18n.t('toast.noMore'));
      }
      return Toast.show(e.message);
    }
  };
}

export function loadChoices(user) {
  return async dispatch => {
    try {
      const role = [UserType.technician, UserType.provider].includes(user.type)
        ? 'vend'
        : 'dent';
      const dentistUrl = `/web/${role}/order/dentist_choices`;
      const clinicUrl = `/web/${role}/order/clinic_choices`;
      const technicianUrl = `/web/${role}/order/technician_choices`;
      const factoryUrl = `/web/${role}/order/factory_choices`;
      dispatch(updateAppState({loading: LoadingStatus.PENDING}));
      const reps = await Promise.all([
        HttpClient.get(dentistUrl),
        HttpClient.get(clinicUrl),
        HttpClient.get(technicianUrl),
        HttpClient.get(factoryUrl),
      ]);
      // console.log(JSON.stringify(reps));
      const payload = {
        dentistOptions: getRepData(reps, 'dentist'),
        clinicOptions: getRepData(reps, 'clinic'),
        technicianOptions: getRepData(reps, 'technician'),
        factoryOptions: getRepData(reps, 'factory'),
      };
      // console.log(payload);
      dispatch(updateOrderList(payload));
    } catch (e) {
      dispatch(updateAppState({loading: LoadingStatus.ERROR}));
      throw e;
    }
  };
}

function getRepData(reps, param) {
  const rep = reps.find(r => r.config.url.indexOf(param) > 0);
  const data = _.get(rep, 'data.data', []);
  if (data[0] === null) {
    return [];
  }
  return data;
}

export function updateParams(payload) {
  return dispatch => {
    dispatch(updateOrderList(payload));
  };
}

export function receive(id) {
  return async () => {
    const url = `/web/dent/order/${id}/receive`;
    await HttpClient.get(url);
  };
}

export function refuse(id) {
  return async () => {
    const url = `/web/vend/order/${id}/refuse`;
    await HttpClient.get(url);
  };
}

export function confirm(id, receiveDay) {
  return async () => {
    const url = `/web/vend/order/${id}/confirmen`;
    await HttpClient.post(url, {receive_day: receiveDay});
  };
}

export function cancel(id) {
  return async (_, getState) => {
    const {user} = getState();
    const url = `/web/${
      [UserType.dentist, UserType.clinic].includes(user.type) ? 'dent' : ''
    }/order/${id}/cancel`;
    await HttpClient.get(url);
  };
}

export function deliver(id) {
  return async () => {
    const url = `/web/vend/order/${id}/deliver`;
    await HttpClient.get(url);
  };
}

export function praise(id, form) {
  return async dispatch => {
    const item = {
      ...form,
      speed: _.get(form, 'speed', 0),
      quality: _.get(form, 'quality', 0),
      service: _.get(form, 'service', 0),
    };
    const url = `/web/dent/order/${id}/praise`;
    await HttpClient.post(url, item);
    dispatch(loadOrders({}, 1));
  };
}

export function assure(id) {
  return async () => {
    const url = `/web/vend/order/${id}/assure`;
    await HttpClient.get(url);
  };
}

export function paid(id) {
  return async () => {
    const url = `/web/dent/order/${id}/paid`;
    await HttpClient.get(url);
  };
}

export function createOrderUpdate(form) {
  return async dispatch => {
    const createOrderRep = await HttpClient.post('/web/dent/order/new', form);
    dispatch(createOrder({...createOrderRep.data.data}));
  };
}

export function addCreateOrderProduct(form) {
  return async dispatch => {
    const item = {...form};
    const createOrderRep = await HttpClient.post('/web/dent/item', item);
    dispatch(createOrderProductAdd({id: createOrderRep.data.data.id}));
  };
}

export function updateCreateOrderProduct(form) {
  return async dispatch => {
    const item = {...form};
    const createOrderRep = await HttpClient.put(
      `/web/dent/item/${form.id}`,
      item,
    );
    dispatch(createOrderProductUpdate({id: createOrderRep.data.data.id}));
  };
}

export function loadOrder(id) {
  return async (dispatch, getState) => {
    const {user} = getState();
    const params = {
      expand:
        'buyer,clinic,seller,factory,praise,items,messages,selections,images',
    };
    const url = `/web/${
      [UserType.clinic, UserType.dentist].includes(user.type) ? 'dent' : 'vend'
    }/order/${id}?${HttpClient.encodeParams(params)}`;
    dispatch(resetOrder());
    const OrderDetailRep = await HttpClient.get(url);
    const {order, messages, items} = OrderDetailRep.data.data;
    order.messages = messages;
    order.items = items;
    dispatch(updateOrder(order));
  };
}

export function updateOrderImages(id, fileList = []) {
  return async dispatch => {
    const url = `/web/dent/order/${id}`;
    const images = fileList.filter(f => f.id).map(row => row.id);
    try {
      await HttpClient.put(url, {images});
      dispatch(updateOrder(loadOrder(id)));
    } catch (e) {
      dispatch(updateAppState({formStatus: FormStatus.FAIL}));
      throw e;
    }
  };
}

export function update(payload) {
  return dispatch => {
    dispatch(updateOrder(payload));
  };
}

export function updateOrderPraise(payload) {
  return (dispatch, getState) => {
    const {order} = getState();
    dispatch(
      updateOrder({
        ...order,
        praise: {
          ...order.praise,
          ...payload,
        },
      }),
    );
  };
}
